﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Skugo.Core;

namespace Skugo.StandardPlugins
{
    /// <summary>
    /// Interaction logic for Tree.xaml
    /// </summary>
    public partial class TreeForm : UserControl
    {
        public event EventHandler<MouseButtonEventArgs> ItemDoubledClicked;
        public event EventHandler<ItemRenamedEventArgs> ItemRenamed;

        private TextBox LastTextBoxClicked = null;
        private DateTime LastTextBoxClickTime = DateTime.Now;

        private Point DragStart;
        private TreeViewItem DragItem;
        private Tree Owner;

        const long QuickClickMs = 500;

        public TreeForm(Tree owner)
        {
            this.Owner = owner;
            InitializeComponent();
        }

        private void OnItemDoubleClick(Object sender, MouseButtonEventArgs args)
        {
            if (this.ItemDoubledClicked != null)
            {
                this.ItemDoubledClicked(sender, args);
            }
        }

        private void OnTextMouseDown(object sender, MouseButtonEventArgs e)
        {
            var textBox = sender as TextBox;
            var item = (textBox.TemplatedParent as FrameworkElement).TemplatedParent as TreeViewItem;

            if (item.IsSelected)
            {
                this.LastTextBoxClicked = textBox;
                this.LastTextBoxClickTime = DateTime.Now;
                e.Handled = true;
            }
            else
            {
                this.LastTextBoxClicked = null;
            }
        }

        private void OnTextMouseUp(object sender, MouseButtonEventArgs e)
        {
            var textBox = sender as TextBox;
            var item = (textBox.TemplatedParent as FrameworkElement).TemplatedParent as TreeViewItem;

            if (item.IsSelected && textBox == this.LastTextBoxClicked)
            {
                var timeDiff = DateTime.Now - this.LastTextBoxClickTime;

                if (timeDiff.Milliseconds < QuickClickMs)
                {
                    textBox.Focusable = true;
                    textBox.Cursor = null;
                    //textBox.BorderThickness = new Thickness(1);
                    textBox.IsReadOnly = false;
                    textBox.Background = System.Windows.Media.Brushes.White;

                    textBox.SelectAll();
                    textBox.Focus();
                    e.Handled = true;

                    textBox.Padding = new Thickness(0);

                    var stack = textBox.Parent as StackPanel;
                    stack.UpdateLayout();
                }
            }
        }

        private void TextBox_LostFocus(object sender, RoutedEventArgs e)
        {
            var textBox = sender as TextBox;
            var item = (textBox.TemplatedParent as FrameworkElement).TemplatedParent as TreeViewItem;

            var node = item.DataContext as TreeNode;

            if (textBox.Text != node.Name)
            {
                node.Name = textBox.Text;

                if (this.ItemRenamed != null)
                {
                    this.ItemRenamed(this, new ItemRenamedEventArgs()
                    {
                        Index = node.Index,
                        Name = node.Name,
                    });
                }
            }

            textBox.Focusable = false;
            textBox.BorderThickness = new Thickness(0);
            textBox.IsReadOnly = true;
            textBox.Background = null;
            textBox.Cursor = Cursors.Arrow;
            textBox.Select(0, 0);
        }

        // Helper to search up the VisualTree
        private static T FindAnchestor<T>(DependencyObject current)
            where T : DependencyObject
        {
            do
            {
                if (current is T)
                {
                    return (T)current;
                }
                current = VisualTreeHelper.GetParent(current);
            }
            while (current != null);
            return null;
        }

        private void View_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            this.DragStart = e.GetPosition(null);
            //this.DragItem = FindAnchestor<TreeViewItem>((DependencyObject)e.OriginalSource);

            DependencyObject dpSource = e.OriginalSource as DependencyObject;

            var element = this.View.InputHitTest(e.GetPosition(this.View)) as DependencyObject;

            if (element != null)
            {
                this.DragItem = FindAnchestor<TreeViewItem>(element);
            }
            else
            {
                this.DragItem = null;
            }
        }

        private void View_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed && this.DragItem != null)
            {
                // Get the current mouse position
                Point mousePos = e.GetPosition(null);

                // Get how much we moved from when we started
                Vector diff = this.DragStart - mousePos;

                // If the difference is enough to begin a drag...
                if (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
                    Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)
                {
                    var node = (TreeNode)this.DragItem.DataContext;
                    var ourData = new PluginDragData(this.Owner, node.Serialize(this.Owner.TreeId));
                    var dataObject = new DataObject(PluginDragData.Format, ourData);
                    DragDrop.DoDragDrop(this.DragItem, dataObject, DragDropEffects.All);
                }
            }
        }

        private void View_MouseLeave(object sender, MouseEventArgs e)
        {
            this.DragItem = null;
        }

        private void View_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            this.DragItem = null;
        }
    }


    public class ItemRenamedEventArgs : EventArgs
    {
        public Int32 Index;
        public String Name;
    }
}
